<!--
 * @Author: 无聊 7989314+Hwz1997@user.noreply.gitee.com
 * @Date: 2025-07-08 08:35:19
 * @LastEditors: 无聊 7989314+Hwz1997@user.noreply.gitee.com
 * @LastEditTime: 2025-09-26 14:37:10
 * @FilePath: \keep_motion_manger\src\components\importDialog\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
    <el-drawer :title="title" size="80%" :model-value="visible" destroy-on-close :before-close="beforeClose">
        <div class="collapse-block">
            <el-collapse v-model="activeNames">
                <el-collapse-item v-for="(item, index) in props.editItems" :key="item.block" :title="item.label" :name="item.block">
                    <el-form v-if="item.layout === 'form'" :model="editForms[index]" :rules="props.rules[index]" :ref="editFormRefs[index]" class="mulitDrawer-form">
                        <template v-for="subItme in item.items.filter(el => el.type !== 'forbidden')" :key="subItme.vModel">
                            <el-form-item :label="subItme.label" class="form-item" :prop="subItme.vModel">
                                <el-input v-if="subItme.type === 'input'" v-model="editForms[index][subItme.vModel]" :disabled="!canEdit || subItme.forbidden" />
                                <el-switch v-else-if="subItme.type === 'switch'" v-model="editForms[index][subItme.vModel]" :disabled="!canEdit || subItme.forbidden" />
                                <el-select v-else-if="subItme.type === 'select'" v-model="editForms[index][subItme.vModel]" placeholder="请选择" clearable :disabled="!canEdit || subItme.forbidden" >
                                    <el-option
                                    v-for="option in subItme.options"
                                    :key="option.value"
                                    :label="option.label"
                                    :value="option.value"
                                    />
                                </el-select>
                                <el-rate v-else-if="subItme.type === 'rate'" v-model="editForms[index][subItme.vModel]" :disabled="!canEdit || subItme.forbidden" allow-half show-score></el-rate>
                                <el-input-tag v-else-if="subItme.type === 'tag'" v-model="editForms[index][subItme.vModel]" :max="5" clearable :disabled="!canEdit || subItme.forbidden"></el-input-tag>
                                <el-date-picker
                                    v-else-if="subItme.type === 'date'"
                                    v-model="editForms[index][subItme.vModel]"
                                    type="date"
                                    placeholder="选择日期"
                                    :disabled="!canEdit || subItme.forbidden" 
                                />
                                <el-upload
                                    v-else-if="subItme.type === 'upload'"
                                    class="avatar-uploader"
                                    :action="`${baseUrl}${subItme.action(editItems[0].items[0].initialValue)}`"
                                    :headers="uploadHeaders"
                                    :show-file-list="false"
                                    :on-success="handleAvatarSuccess.bind(this, index, subItme.vModel)"
                                    :before-upload="beforeAvatarUpload.bind(this, subItme.fileType)"
                                    :disabled="!canEdit || subItme.forbidden"
                                >   
                                    <div class="avatar-uploader-container" v-if="editForms[index][subItme.vModel]">
                                        <el-image v-if="!subItme.fileType" :src="`${baseUrl}${editForms[index][subItme.vModel]}`" class="avatar" fit="cover"/>
                                        <video v-else-if="subItme.fileType === 'video'" controls :src="`${baseUrl}${editForms[index][subItme.vModel]}`" class="avatar" />
                                    </div>
                                    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
                                </el-upload>
                            </el-form-item>
                        </template>
                    </el-form>
                    <el-tabs v-if="item.layout === 'tabs'" tab-position="left" class="drawer-tabs">
                        <el-tab-pane class="drawer-tab-pane" v-for="(tab, tabIndex) in item.initialValue" :key="tab[item.vModel.tabPane]" :label="tab[item.vModel.tabPane]">
                            <el-card class="drawer-card" v-for="(card, cardIndex) in tab[item.vModel.tabContain]" :key="card[item.vModel.cardName]" shadow="hover" header-class="drawer-card-header" body-class="drawer-card-body" footer-class="drawer-card-footer">
                                <template #header>
                                    <div class="line-name">{{card[item.vModel.cardName]}}</div>
                                </template>
                                <video v-if="card[item.vModel.cardUrl]" :src="`${baseUrl}${card[item.vModel.cardUrl]}`" class="drawer-card-video" />
                                <template #footer>
                                    <div class="line-resources">{{`已有资源数量： ${card[item.vModel.cardResources].length}`}}</div>
                                    <div class="line-sub">{{`时长：${card[item.vModel.cardSub]}分钟`}}</div>
                                </template>
                                <div class="controller-contain">
                                    <el-button type="primary" v-if="dialogType === 'view'" :icon="View" @click="viewCard(index, tabIndex, cardIndex)" text>查看</el-button>
                                    <el-button type="primary" v-if="dialogType !== 'view'" :icon="Edit" @click="editCard(index, tabIndex, cardIndex)" text>编辑</el-button>
                                    <el-button type="danger" v-if="dialogType !== 'view'" :icon="Delete" @click="deleteCard(index, tabIndex, cardIndex)" text>删除</el-button>
                                </div>
                            </el-card>
                            <el-card class="drawer-card" shadow="hover" v-if="canEdit">
                                <el-icon  class="drawer-full-icon" @click="addCard(index, tabIndex)"><Plus /></el-icon>
                            </el-card>
                        </el-tab-pane>
                        <el-tab-pane class="drawer-tab-pane" label="新增" v-if="canEdit">
                            <el-input v-model="tabPaneName[index]" :placeholder="`请输入${item.label.slice(0, 2)}名称`"/>
                            <el-button type="primary" @click="addTab(index, tabPaneName[index])" ref="addButtonRef">新增</el-button>
                        </el-tab-pane>
                    </el-tabs>
                </el-collapse-item>
            </el-collapse>
        </div>
        <template #footer>
            <span>
                <el-button @click="beforeClose">取消</el-button>
                <el-button type="primary" @click="handleSuccess" v-if="canEdit">确定</el-button>
            </span>
        </template>
    </el-drawer>
    <EditDialog
        ref="editDialogRef"
        :visible="editDialogVisible"
        :dialogType="editDialogType"
        :editItems="editDialogItems"
        @successCallBack="editCallBack"
        @close="handleClose"
    />
</template>

<script setup>

import { ref, reactive, onMounted, defineProps, defineEmits, computed, watch, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Plus, Edit, Delete, View } from '@element-plus/icons-vue'

import EditDialog from '@/components/editDialog/index.vue';

const baseUrl = import.meta.env.VITE_BASE_URL;
import { dictDataApi } from '@/api';
import './index.css';

const props = defineProps({
    visible: {
        type: Boolean,
        default: () => false
    },
    dialogType: {
        type: String,
        default: () => 'add'
    },
    editItems: {
        type: Array,
        default: () => []
    },
    rules: {
        type: Object,
        default: () => ([])
    }
});

const editFormRefs = ref([]);

const emit = defineEmits(['close', 'successCallBack']);

const editForms = reactive([]);
const activeNames = ref([]);
const tabPaneName = ref([]);
const tabPaneList = ref([]);
const addButtonRef = ref(null);
const canEdit = computed(() => {
    return props.dialogType !== 'view';
});
const title = computed(() => {
    return canEdit.value ? (props.dialogType === 'add' ? '新增' : '编辑') : '查看';
});
const uploadHeaders = computed(() => {
    return {
        Authorization: sessionStorage.getItem("role") + ' ' + sessionStorage.getItem('token'),
    }
})

const editDialogVisible = ref(false);
const editDialogType = ref('edit');
const editDialogRef = ref(null);
const editDialogItems = ref([]);
const editIndexCache = ref({});

// 模拟根据 code 获取下拉框选项
const getOptions = async (code) => {
  // 这里可以根据 code 调用接口获取对应选项
  const res = await dictDataApi.getDictData({code});
  if (res.code === 200) return res.data.rows;
  return [];
};
// 初始化表单数据
const initForm = () => {
    props.editItems.forEach((item, index) => {
        activeNames.value.push(item.block); 
        editForms[index] = {};
        if(item.layout === 'tabs'){
            editForms[index] = item.initialValue;
        }
        else if(item.layout === 'form') item.items.forEach(subItem => {
            editForms[index][subItem.vModel] = subItem.initialValue !== undefined ? subItem.initialValue : '';
        })
    });
};
// 头像上传
const beforeAvatarUpload = (type = 'image', file) => {
    const allowHash = {
        image: ['image/jpeg', 'image/png', 'image/gif'],
        video: ['video/mp4', 'video/avi', 'video/mkv']
    }
    const tipsTextHash = {
        image: '图片',
        video: '视频'
    }
    const tipsTypeHash = {
        image: 'JPG, PNG, GIF',
        video: 'MP4, AVI, MKV'
    }
    const allowerList = allowHash[type];
    const isAllow = allowerList.includes(file.type);
    if (!isAllow) {
        ElMessage.error(`上传${tipsTextHash[type]}只能是 ${tipsTypeHash[type]} 格式!`);
    }
    return isAllow;
}
// 头像上传成功
const handleAvatarSuccess = (index, itemCode, res) => {
    editForms[index][itemCode] = res.data.file;
}
// 确定
const handleSuccess = async (res) => {
    let valid = true;
    editFormRefs.value.forEach(async (ref) => {
       const validate = await ref.validate();
       if (!validate) valid = false;
    })
    if (!valid) return;
    emit('successCallBack', props.dialogType, editForms);
};

// 关闭前
const beforeClose = (done) => {
    emit('close');
};

// 新增tab
const addTab = (index, name) => {
    editForms[index].push({
        [props.editItems[index].vModel.tabPane]: name,
        [props.editItems[index].vModel.tabContain]: []
    });
    // 修复：使用Vue的方式移除焦点
    nextTick(() => {
        // 创建一个临时元素接收焦点
        const tempElement = document.createElement('span');
        tempElement.setAttribute('tabindex', '-1');
        document.body.appendChild(tempElement);
        tempElement.focus();
        document.body.removeChild(tempElement);
        // 重置输入框
        tabPaneName.value[index] = '';
    });
}
// 新增card
const addCard = (index, tabIndex) => {
    const tabContain = props.editItems[index].vModel.tabContain;
    const cardName = props.editItems[index].vModel.cardName;
    const cardUrl = props.editItems[index].vModel.cardUrl;
    const cardSub = props.editItems[index].vModel.cardSub;
    const cardResources = props.editItems[index].vModel.cardResources;
    editForms[index][tabIndex][tabContain].push({
        [cardName]: `第${editForms[index][tabIndex][tabContain].length + 1}课 未命名`,
        [cardUrl]: '',
        [cardSub]: '',
        [cardResources]: []
    })
}
// 删除card
const deleteCard = (index, tabIndex, cardIndex) => {
    const tabContain = props.editItems[index].vModel.tabContain;
    editForms[index][tabIndex][tabContain].splice(cardIndex, 1);
}
// 编辑card
const editCard = (index, tabIndex, cardIndex) => {
    const tabContain = props.editItems[index].vModel.tabContain;
    editDialogType.value = 'edit';
    editDialogVisible.value = true;
    editDialogItems.value = props.editItems[index].editItems;
    initEditItems(editForms[index][tabIndex][tabContain][cardIndex]);
    editIndexCache.value = {
        index,
        tabIndex,
        cardIndex
    }
}
// 查看card
const viewCard = (index, tabIndex, cardIndex) => {
    const tabContain = props.editItems[index].vModel.tabContain;
    editDialogType.value = 'view';
    editDialogVisible.value = true;
    editDialogItems.value = props.editItems[index].editItems;
    initEditItems(editForms[index][tabIndex][tabContain][cardIndex]);
}

const editCallBack = (type, data) => {
    if(type === 'edit'){
        const {index, tabIndex, cardIndex} = editIndexCache.value;
        const tabContain = props.editItems[index].vModel.tabContain;
        editForms[index][tabIndex][tabContain][cardIndex] = data;
    }
    editDialogVisible.value = false;
}
const handleClose = () => {
    editDialogVisible.value = false;
}

const initEditItems = (row) => {
  editDialogItems.value.forEach(item => {
    item.initialValue = row[item.vModel];
  })
}
onMounted(async () => {
  // 先获取所有下拉框的选项
  const optionPromises = props.editItems.map((item) => {
    if(item.layout === 'form') item.items.filter(subItem => subItem.type === 'select')
    .map(async (subItem) => {
      const options = await getOptions(subItem.optionsCode);
      subItem.options = options;
    });
  })
  await Promise.all(optionPromises);
});

watch(() => props.visible, (newVal) => {
    if (newVal) {
        initForm();
    }
})
</script>